#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
typedef double db;
inline int read()
{
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9') { if(ch=='-')f=-1; ch=getchar(); }
	while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+ch-'0'; ch=getchar(); }
	return x*f;
}
const int MAXN=8e5+10,MAXM=5e5+10;
int n;
struct node
{
	int num,x,y,op,ans;
	bool operator<(const node b)const
	{
		return num<b.num;
	}
}a[MAXN],t[MAXN];
struct BIT
{
	int num[MAXM];
	inline int lowbit(int x)
	{
		return x&-x;
	}
	void update(int o,int x)
	{
		while(o<=n)
		{
			num[o]+=x;
			o+=lowbit(o);
		}
		return;
	}
	int query(int o)
	{
		int ret=0;
		while(o)
		{
			ret+=num[o];
			o-=lowbit(o);
		}
		return ret;
	}
}T1;
void CDQ(int l,int r)
{
	if(l==r)return;
	int mid=(l+r)>>1;
	CDQ(l,mid);CDQ(mid+1,r);
	int i=l,j=mid+1,cnt=0;
	while(i<=mid||j<=r)
	{
		if(j>r||(i<=mid&&a[i].x<=a[j].x))
		{
			if(!a[i].op)T1.update(a[i].y,a[i].ans);
			t[++cnt]=a[i++];
		}
		else
		{
			if(a[j].op)a[j].ans+=T1.query(a[j].y);
			t[++cnt]=a[j++];
		}
	}
	for(int i=l;i<=mid;++i)if(!a[i].op)T1.update(a[i].y,-a[i].ans);
	for(int i=l;i<=r;++i)a[i]=t[i-l+1];
	return;
}
int main()
{
	n=read();
	int cnt=0;
	while(true)
	{
		int op=read();
		if(op==3)break;
		else if(op==2)
		{
			int x1=read(),y1=read(),x2=read(),y2=read();
			a[++cnt]=(node){cnt,x1-1,y1-1,1,0};
			a[++cnt]=(node){cnt,x2,y1-1,1,0};
			a[++cnt]=(node){cnt,x1-1,y2,1,0};
			a[++cnt]=(node){cnt,x2,y2,1,0};
		}
		else
		{
			int x=read(),y=read(),z=read();
			a[++cnt]=(node){cnt,x,y,0,z};
		}
	}
	CDQ(1,cnt);
	sort(a+1,a+1+cnt);
	for(int i=1;i<=cnt;++i)
		if(a[i].op)
		{
			printf("%d\n",a[i+3].ans+a[i].ans-a[i+1].ans-a[i+2].ans);
			i+=3;
		}
	return 0;
}
